package com.sfm.tour;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.PopupWindow;
import android.widget.Spinner;
import android.widget.Toast;

/**
 * 
 * This application demonstrates the use of camera in android. On creation of
 * the activity, the camera preview starts which allows the user to preview
 * before capturing an image. The image can be captured using the button that is
 * provided. On click of the button the callback method
 * <code> PictureCallback() </code> is called. The callback handles storing the
 * captured image in jpeg format into the external storage device. A SurfaceView
 * is created for the camera preview. The Activity implements the
 * SurfaceHolder.Callback to get notifications about the changes in the surface.
 * 
 * The CAMERA permissions need to be declared in the AndroidManifest.xml file in
 * order to access the camera device. <uses-feature> element is used to declare
 * the features of the camera that will be used by the application.
 */

public class CameraActivity extends Activity implements SurfaceHolder.Callback {

    protected Camera        camera;
    protected SurfaceView   surfaceView;
    protected SurfaceHolder surfaceHolder;
    protected ImageButton   cameraButton;
    private File            path;
    private int             i = 0;
    Movie movieToAdd_cam;
    Spinner spinnerMovieList_cam;
    Location location_cam;
    XMLFunctions objXml_cam;

    @Override
    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        /*
         * Set the camera preview to be full screen without the notification bar
         */
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.camera);

        /*
         * Get the external storage directory path Generally /mnt/sdcard/
         */
        path = Environment.getExternalStorageDirectory();

        /*
         * Get the SurfaceView which is defined in the resources file using the
         * resource ID
         */
        surfaceView = (SurfaceView) findViewById(R.id.surfaceCamera);

        /*
         * Surface holder allows us to control the changes to the surface. A
         * Callback interface is registered in order to control changes to the
         * surface.
         */
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        //Spinner Load
       /*
        objXml_cam= new XMLFunctions();
        
        ArrayList<String> movieList_cam = objXml_cam.getAllMovies(this);
        //Load the movie list in the spinner
        spinnerMovieList_cam = (Spinner) findViewById(R.id.spinner_movielist_cam);
        //spinnerMovie.setOnItemSelectedListener(new MovieOnItemSelectedListener());        
        ArrayAdapter<String> adapterMovieList_cam = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, movieList_cam);
        
        adapterMovieList_cam.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerMovieList_cam.setAdapter(adapterMovieList_cam);      
        
        //Get current location
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        if (locationManager == null) {
            Toast.makeText(CameraActivity.this,
                    "Location Manager Not Available", Toast.LENGTH_SHORT)
                    .show();
            return;
        }
        location_cam = locationManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (location_cam == null)
            location_cam = locationManager
                    .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        */
    }

   
    /*
     * This callback can be used to play shutter sound and such since this
     * callback method is called when the image is captured by the sensor
     */
    ShutterCallback        shutterCallback = new ShutterCallback() {
                                               public void onShutter() {
                                                   Log.v("Camera", "picturecallback");
                                               }
                                           };

    /*
     * This callback is called immediately after the surface is first created.
     * Obtain an instance of the camera when the surface is created.
     */
    public void surfaceCreated(SurfaceHolder holder) {
    	
        camera = Camera.open();
        Camera.Parameters parameters = camera.getParameters(); 
        //camera id is set to 2 to access the front camera
        parameters.set("camera-id", 2); 
        camera.setParameters(parameters);
        
    }

    /*
     * This callback is called when there are any structural changes to the
     * surface.
     */
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        View root = findViewById(R.id.root);
        camera.stopPreview();

        /*
         * Camera parameters can be modified by modifying the object that is
         * returned by getParameters()
         */
        Camera.Parameters p = camera.getParameters();

        /*
         * Determine supported preview sizes and and set the preview size which
         * best matches the device's screen resolution.
         */
        List<Size> supportedSizes = p.getSupportedPreviewSizes();
        Size previewSize = determinePreviewSize(supportedSizes, root.getWidth(), root.getHeight());

        /*
         * Switch camera to portrait mode. TODO: Handle upside down orientations
         * properly
         */
        if (root.getWidth() < root.getHeight()) {
            camera.setDisplayOrientation(90);
        }
        p.setPreviewSize(previewSize.width, previewSize.height);

        p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        camera.setParameters(p);

        try {
            /*
             * setPreviewDisplay() must be called before calling startPreview()
             * This method sets the surface required for the camera preview. A
             * fully initialized SurfaceHolder must be passed to this method.
             */
            camera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*
         * Layout the surfaceView correctly. It might not cover the whole
         * screen, depending in the screen's and camera's aspect ratio.
         */
        float previewAspectRatio = (float) (previewSize.width) / previewSize.height;
        if (root.getWidth() > root.getHeight()) {
            surfaceView.layout(0, 0, (int) (root.getHeight() * previewAspectRatio),
                    root.getHeight());
        } else {
            surfaceView.layout(0, 0, root.getWidth(), (int) (root.getWidth() * previewAspectRatio));
        }

        /*
         * Starts the live preview required for camera
         */
        camera.startPreview();
    }

    /*
     * This callback is called just before the surface is being destroyed. Since
     * camera is a shared resource it is good practice to release the resource
     * when not using it.
     */
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.e("Camera", "surfaceDestroyed");
        if(camera != null) {
        camera.setPreviewCallback(null);
        
        camera.stopPreview();
        camera.release();
        camera = null;
        }
    }

    /**
     * Determine preview size based on the supported preview sizes. The preview
     * size is the maximum preview size supported which is less or equal to the
     * device's screen resolution. To test the best matching size both portrait
     * and landscape screen orientations are tested.
     * 
     * @param sizes
     *            The preview sizes supported by the device's camera.
     * 
     * @param width
     *            The device's screen width.
     * 
     * @param height
     *            The device's screen height.
     * 
     * @return The determined preview size.
     */
    private Size determinePreviewSize(List<Size> sizes, int width, int height) {
        if (height > width) {
            int temp = width;
            width = height;
            height = temp;
        }

        for (Size s : sizes) {
            if (s.width <= width && s.height <= height) {
                return s;
            }

            if (s.width <= height && s.height <= width) {
                return s;
            }
        }
        return null;
    }
    
    
    public void launchMapView (View v) {
    	Intent mapIntent = new Intent(getApplicationContext(), SFMapTagActivity.class);
        startActivity(mapIntent);      
    	
    }
    
    PopupWindow popupWindow;
    public void tagLocation (View v) {
    	 LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        popupWindow = new PopupWindow(inflater.inflate(R.layout.tag,null, false),400,400,true);
          popupWindow.showAtLocation(findViewById(R.id.surfaceCamera), Gravity.CENTER, 0,0);
     
    }
    
    public void closePopup(View v) {
    	popupWindow.dismiss();
    }
    
    public void saveTag(View v) {
    	
    	EditText time = (EditText) findViewById(R.id.txt_time_cam);
    	EditText desc = (EditText) findViewById(R.id.txt_description_cam);
    	String title = spinnerMovieList_cam.getSelectedItem().toString();
    	movieToAdd_cam = new Movie(title);
    	LocationData locToAdd =new LocationData(Double.toString(location_cam.getLatitude()),Double.toString(location_cam.getLatitude()));
				locToAdd.setDescription(desc.getText().toString());
				locToAdd.setTime(time.getText().toString());
    	movieToAdd_cam.addLocation(locToAdd);
    	boolean result =objXml_cam.addMovieTag(getApplicationContext(),movieToAdd_cam);
    	if(result) {

        	Toast.makeText(getApplicationContext(),"Location Tagged!",Toast.LENGTH_SHORT).show();
    	}else {

        	Toast.makeText(getApplicationContext(),"Oops! Tag failed. Try Again.",Toast.LENGTH_SHORT).show();
    	}

    //	@TODO
    }
}